home *** CD-ROM | disk | FTP | other *** search
- ;* SHOW.ASM - Text file displayer for DOS.
-
- TITLE Show
- .MODEL small, pascal ; This code also works in tiny model
- .DOSSEG
-
- INCLUDE show.inc
- INCLUDE dos.inc
- INCLUDE bios.inc
-
- .STACK
-
- .DATA
-
- ; Status line
-
- stLine BYTE "Line: 12345 "
- stFile BYTE "File: 12345678.123 "
- BYTE "Quit: Q Next: ESC Move: PGUP PGDN HOME END"
-
- ; Variables for screen handling
-
- yCur WORD 1
- yMax WORD 24 ; Number of rows - status line takes one more
- iMode BYTE 0 ; Initial mode
- iPage BYTE 0 ; Initial display page
- atInit BYTE 0 ; Initial attribute
- shCsr WORD 0 ; Initial cursor shape
- bCsrSta BYTE 0 ; 0 = cursor visible, position unchanged
- ; 1 = cursor invisible, position unchanged
- ; 2 = cursor invisible, position changed
-
- fNewVid BYTE 0 ; Video change flag
- fCGA BYTE 1 ; CGA flag - default yes
-
- segVid WORD SEG_CLR ; Video buffer address - default color
-
- atSta BYTE STAT_CLR ; Status line color
- celScr LABEL WORD ; Cell (character and attribute)
- chScr BYTE ' ' ; Initialize to space
- atScr BYTE SCRN_CLR ; Screen color
-
- ; Buffer variables
-
- fpBuf LABEL FAR PTR
- offBuf WORD 0 ; Position in buffer (offset)
- segBuf WORD 0 ; Base of buffer (segment)
- cbBuf WORD 0 ; Length of buffer
-
- ; File information
-
- hFileIn WORD 0 ; Holds file handle on open
-
- ; Buffer for file spec and structure for file info
-
- achBuf BYTE NAME_MAX, ? ; Buffer format for string input
- stFiles BYTE NAME_MAX DUP (0); File spec string
- fiFiles FILEINFO <> ; Wild card entry structure
- cFiles WORD 0 ; Count of 1 or 0 files remaining
-
- ; Messages
-
- stMsg1 BYTE 13, 10, 13, 10, "Enter filename: $"
- stMsg2 BYTE 13, 10, "File problem. Try again? $"
- stMsg3 BYTE 13, 10, "File too large: $"
- stMsg4 BYTE 13, 10, "Memory problem.", 13, 10, "$"
- stMsg5 BYTE 13, 10, "Must have DOS 2.0 or higher", 13, 10, "$"
-
- ; Call table
-
- achKeys BYTE 71, 72, 73, 79, 80, 81, 'q', 'Q'; Key table
- afnKeys WORD HomeKey ; Corresponding procedures
- WORD UpKey
- WORD PgUpKey
- WORD EndKey
- WORD DownKey
- WORD PgDnKey
- WORD Quit
- WORD Quit
- WORD UnknownKey
-
- .CODE
- .STARTUP
-
- ; Adjust memory allocation (works for tiny or small model)
-
- mov bx, sp ; Convert stack pointer to paragraphs
- mov cl, 4 ; to get stack size
- shr bx, cl
- mov ax, ss ; Add SS to get end of program
- add ax, bx
- mov bx, es ; Get start of program
- sub ax, bx ; Subtract start from end
- inc ax
- @ModBlock ax ; Release memory after program
-
- ; Check DOS
-
- @GetVer ; Get DOS version
- .IF al < 2 ; Requires DOS 2.0
- @ShowStr stMsg5 ; else error and quit
- int 20h
- .ENDIF
-
- ; Get command line and copy to filename buffer
-
- mov di, 80h ; PSP offset of command line
- mov bl, es:[di] ; Get length from first byte
- sub bh, bh
- or bx, bx
- je Prompter
-
- mov WORD PTR es:[bx+81h], 0 ; Convert to ASCIIZ
- mov al, ' ' ; Character to check for
- inc di ; Advance beyond count
- mov cx, 0FFFFh ; Don't let count interfere
- repe scasb ; Find first nonspace
- dec di ; Adjust
-
- mov si, di ; Filename source
- mov di, OFFSET stFiles ; Name buffer destination
- mov bx, ds ; Save segment registers
- mov dx, es
- mov ds, dx ; DS = ES
- mov es, bx ; ES = DS
- mov cx, NAME_MAX ; Count = max filename allowed
-
- .REPEAT
- lodsb ; Copy characters
- .BREAK .IF (al == ' ') || (al == 0) ; Stop at space or null
- stosb
- .UNTILCXZ ; Until name exceeds max
-
- mov ds, bx ; Restore segments
- mov es, dx
- mov BYTE PTR [di], 0
- jmp FindFile
- NoFile:
-
- @ShowStr stMsg2 ; Prompt to try again
- @GetChar 0, 1, 0
- and al, 11011111y ; Convert key to upper case
- .IF al != 'Y' ; If not yes,
- jmp quit ; quit
- .ENDIF
-
- ; Prompt for file
-
- Prompter:
- @ShowStr stMsg1 ; Prompt for file
- @GetStr achBuf, 0 ; Get response as ASCIIZ
-
- ; Find first (or only) file in file spec
-
- FindFile:
-
- @SetDTA <OFFSET fiFiles> ; Set DTA to file info structure
- ; Don't need DTA for anything else,
- ; so no need to restore it
- @GetFirst stFiles,0 ; Find a matching file
-
- jc NoFile ; If not found, prompt for new
- inc cFiles ; Some files remaining
-
- INVOKE GetVid
-
- ; Main program loop to process files
-
- .REPEAT
-
- ; Copy filename to file spec
-
- mov bCsrSta, 2 ; Cursor hidden, position unchanged
- INVOKE GetNamePos, ; Get filename position in file spec
- ADDR stFiles
-
- mov si, OFFSET fiFiles.fiFileName ; Point to source name
- push ds ; ES = DS
- pop es
- mov di, ax ; Load address from return value
-
- .REPEAT ; Copy to (and including) null
- movsb
- .UNTIL BYTE PTR [si-1] == 0
-
- ; Copy filename to status line
-
- mov si, OFFSET fiFiles.fiFileName ; Point to source name
- mov di, OFFSET stFile[FILE_POS] ; Point to status line
-
- sub cx, cx ; Count characters
- .REPEAT
- lodsb ; Copy to (but excluding) null
- .BREAK .IF al == 0
- stosb
- inc cx
- .UNTIL 0
-
- mov bx, 12 ; Calculate blank spaces to fill
- sub bx, cx
- mov al, ' ' ; Fill rest of name space with blanks
- mov cx, bx
- rep stosb
-
- ; Skip any file that is larger than 64K
-
- .IF WORD PTR fiFiles.fiSize[2] != 0 ; Error if high word isn't 0
- mov bCsrSta, 1 ; Cursor hidden, position unchanged
-
- @ShowStr stMsg3 ; Display error string and filename
- @Write fiFiles.fiFileName, cx, 1
-
- .IF cFiles ; If files remaining,
- @GetChar 0 ; get a key
- .ENDIF
- .ENDIF
-
- ; Allocate dynamic memory for file buffer
-
- mov ax, WORD PTR fiFiles.fiSize[0] ; Get length
- mov cbBuf, ax ; Save
- mov offBuf, 0
- mov cl, 4 ; Convert to paragraphs
- shr ax, cl
- inc ax ; Zero adjust
-
- @GetBlock ax ; Try to allocate 64K
- .IF carry? ; Display error and quit if
- @ShowStr stMsg4 ; request failed
- jmp Quit
- .ENDIF
- mov segBuf, ax ; Save buffer segment
-
- ; Open file and read contents into buffer
-
- @OpenFile stFiles, 0 ; Try to open
- jc NoFile ; If fail, get a new file
- mov hFileIn, ax ; Save handle
-
- push ds
- @Read fpBuf, cbBuf, hFileIn ; Read file
- pop ds
- .IF carry?
- jmp NoFile ; If read error try again
- .ENDIF
-
- ; Search back for EOF marker and adjust if necessary
-
- mov di, cbBuf ; Load file length
- dec di ; and adjust
- mov es, segBuf
- std ; Look backward for 255 characters
- mov cx, 0FFh
- .IF cx >= di
- mov cx, di
- .ENDIF
-
- mov al, 1Ah ; Search for EOF marker
- repne scasb
- cld
- .IF cx != 0 ; If found,
- inc di ; adjust and save file size
- mov cbBuf, di
- .ENDIF
-
- ; Show a screen of text and allow commands
-
- INVOKE Show
-
- @CloseFile hFileIn ; Yes? Close file
- @FreeBlock segBuf ; Release buffer
-
- @GetNext
-
- .IF carry?
- dec cFiles
- .ENDIF
- .UNTIL !cFiles
-
- ; Fall through to Quit
-
- Quit PROC
-
- cmp bCsrSta, 1 ; Check cursor status
- jg csrvislast ; 2 - Make cursor visible on last line
- je csrvis ; 1 - Make cursor visible
- jmp csrasis ; 0 - Leave cursor as is
-
- csrvislast:
- mov dx, yMax ; Load last row and first column
- xchg dl, dh
- mov cx, dx ; Make row the same
- mov dl, 79
- @Scroll 0, atInit ; Clear last line to original color
- sub dl, dl ; Column 0
- @SetCsrPos ; Set cursor
- csrvis: ; Fall through
- ; Restore cursor attribute
- @SetCsrSize <BYTE PTR shCsr[1]>, <BYTE PTR shCsr[0]>
-
- csrasis:
- .IF fNewVid == 1
- @SetMode iMode ; Restore video mode, page, and cursor
- @SetPage iPage
- .ENDIF
-
- .EXIT 0 ; Quit
-
- Quit ENDP
-
-
- Show PROC
-
- ; Display first page
-
- mov yCur, 1 ; Reinitialize
- INVOKE Pager, ; Start at 0
- 0
-
- ; Handle keys
-
- .REPEAT
-
- @GetChar 0, 0, 0 ; Get a key
-
- .BREAK .IF al == 27 ; If ESC get out for next file
-
- ; If null or E0 (for extended keyboard), it's an extended key
- .IF (al == 0) || (al == 0E0h)
- @GetChar 0, 0, 0 ; Get extended code
- .ENDIF
-
- push ds ; ES = DS
- pop es
- mov di, OFFSET achKeys ; Load address and length of key list
- mov cx, LENGTHOF achKeys + 1
- repne scasb ; Find position and point to key
- sub di, OFFSET achKeys + 1
- shl di, 1 ; Adjust pointer for word addresses
- call afnKeys[di] ; Call procedure
- .UNTIL 0
-
- ret
- Show ENDP
-
- HomeKey:
- mov offBuf, 0 ; HOME - set position to 0
- mov yCur, 1
- INVOKE Pager, offBuf
- retn
-
- UpKey:
- INVOKE Pager, -1 ; UP - scroll backward 1 line
- retn
-
- PgUpKey:
- mov ax, yMax ; PGUP - Page back
- neg ax
- INVOKE Pager, ax
- retn
-
- EndKey:
- mov ax, cbBuf ; END - Get last byte of file
- dec ax ; Zero adjust
- mov offBuf, ax ; Make it the file position
- mov yCur, -1 ; Set illegal line number as flag
- mov ax, yMax ; Page back
- neg ax
- INVOKE Pager, ax
- retn
-
- DownKey:
- INVOKE Pager, 1 ; DOWN - scroll forward 1 line
- retn
-
- PgDnKey:
- INVOKE Pager, yMax ; PGDN - page forward
- retn
-
- UnknownKey:
- retn ; Ignore unknown key
-
-
- ;* GetVid - Gets the video mode and sets related global variables.
- ;*
- ;* Params: None
- ;*
- ;* Return: Number of lines in current mode (25, 43, or 50)
-
- GetVid PROC
-
- ; Adjust for current mode and and video adapter
-
- INVOKE IsEGA ; EGA (or VGA)?
- .IF ax != 0 ; If 0 must be CGA or MA
- mov yMax, ax ; Load rows
- dec fCGA ; Not CGA
- .ENDIF
-
- @GetMode ; Get video mode
- mov iMode, al ; Save initial mode and page
- mov iPage, bh
- mov dl, al ; Work on copy
- cmp dl, 7 ; Is it mono 7?
- je loadmono ; Yes? Set mono
- cmp dl, 15 ; Is it mono 15?
- jne graphchk ; No? Check graphics
- loadmono:
- mov segVid, SEG_MONO ; Load mono address
- mov atSta, STAT_BW ; Set B&W defaults for status line
- mov atScr, SCRN_BW ; and screen background
- dec fCGA ; Not CGA
- cmp al, 15 ; Is it mono 15?
- jne exit ; No? Done
- mov dl, 7 ; Yes? Set standard mono
- jmp chmode
- graphchk:
- cmp dl, 7 ; 7 or higher?
- jg color ; 8 to 14 are color (7 and 15 done)
- cmp dl, 4 ; 4 or higher?
- jg bnw ; 5 and 6 are probably black and white
- je color ; 4 is color
- test dl, 1 ; Even?
- jz bnw ; 0 and 2 are black and white
- color: ; 1 and 3 are color
- cmp dl, 3 ; 3?
- je exit ; Yes? Done
- mov dl, 3 ; Change mode to 3
- jmp chmode
- bnw:
- mov atSta, STAT_BW ; Set B&W defaults for status line
- mov atScr, SCRN_BW ; and screen background
- cmp dl, 2 ; 2?
- je exit ; Yes? Done
- mov dl, 2 ; Make it 2
- chmode:
- @SetMode dl ; Set video mode
- @SetPage 0 ; Set video page
- mov fNewVid, 1 ; Set flag
- exit:
- @GetCsr ; Get cursor shape (ignore position)
- mov shCsr, cx ; Save shape
- @GetCharAtr ; Read the cell at the cursor
- mov atInit, ah ; Save attribute
- @SetCsrSize 20h, 20h ; Turn off cursor (invisible shape)
-
- ret
-
- GetVid ENDP
-
-
- END
-